package system.track;

import system.communication.Monitor;
import system.ui.Engine;

/**
 *
 * @author David
 */
public class Switch
{
    private int id;
    private Block entrance;
    private Block exit_180;
    private Block exit_90;
    private SwitchAngle state;

    public Switch()
    {
        state = SwitchAngle.ONE_EIGHTY_DEGREES;
    }

    public Switch(int id)
    {
        this();
        setID(id);
    }

    /**
     * Registers an ID to a switch.
     * 
     * @param id an id that corresponds to a switch on the layout.
     */
    public void setID(int id)
    {
        this.id = id;
        setAngle(state);
    }

    /**
     * Retrieves the switch's ID.
     * 
     * @return an id that corresponds to a switch in the layout.
     */
    public int getID()
    {
        return this.id;
    }
    
    /**
     * Sets the angle of the switch.
     * 
     * @param angle one of the instantiated objects of the 
     * <code>SwitchAngle</code> enum.
     */
    public synchronized void setAngle(SwitchAngle angle)
    {
        this.state = angle;
        Monitor.getInstance().setSwitch(id, angle);
        Engine.getInstance().postSwitchAngle(id, angle);
    }

    /**
     * Retrieves the current angle setting of the switch.
     * 
     * @return an instantiated object of the <code>SwitchAngle</code> enum
     * representing the current angle of the switch.
     */
    public SwitchAngle getAngle()
    {
        return state;
    }

    /**
     * Sets the block placed at the entrance of the switch.
     * 
     * @param block the block object at the entrance to the switch.
     */
    public void setEntrance(Block block)
    {
        this.entrance = block;
    }

    /**
     * Retireves the block placed at the entrance of the switch.
     * 
     * @return the block object at the entrance of the switch.
     */
    public Block getEntrance()
    {
        return this.entrance;
    }

    /**
     * Registers <code>block</code> to exit <code>angle</code>.
     * 
     * @param angle one of the <code>SwitchAngle</code> enum objects that 
     * specifiy which exit to register with.
     * @param block the block to register to the exit.
     */
    public void setExit(SwitchAngle angle, Block block)
    {
        switch (angle)
        {
            case NINETY_DEGREES:
                this.exit_90 = block;
                break;
            case ONE_EIGHTY_DEGREES:
                this.exit_180 = block;
                break;
        }
    }

    /**
     * Retrieves the block placed at the exit <code>angle</code>.
     * 
     * @param angle one of the <code>SwitchAngle</code> enum objects that
     * specify which exit to retrieve.
     * @return the block registerd with the exit specified by <code>angle</code>.
     */
    public Block getExit(SwitchAngle angle)
    {
        Block returnVal = null;
        switch (angle)
        {
            case NINETY_DEGREES:
                returnVal = this.exit_90;
                break;
            case ONE_EIGHTY_DEGREES:
                returnVal = this.exit_180;
                break;
        }
        return returnVal;
    }

}
